package com.flaremars.picker.fragments.common;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.flaremars.picker.R;
import com.flaremars.picker.entities.common.BaseEntity;
import com.flaremars.picker.utils.StringUtils;
import com.flaremars.picker.utils.http.newhttp.HttpHelper;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author by FlareMars on 2016/3/10.
 * 实现简单的上拉加载/下拉刷新/状态显示的ListFragment
 */
public abstract class BaseListFragment<T extends BaseEntity> extends Fragment {

    public enum FragmentStatus {
        NO_DATA,
        NETWORK_ERROR,
        NORMAL,
        REQUEST_ERROR
    }

    private String DATA_REQUEST_URL = "";

    private ProgressBar waitingProgressBar;

    private SwipeRefreshLayout swipeRefreshLayout;

    private RecyclerView contentRecyclerView;

    private LinearLayoutManager layoutManager;

    private RecyclerView.Adapter adapter;

    private TextView statusMsgTv;

    private RelativeLayout statusMsgPanel;

    private List<T> objectList;

    private int lastVisibleItem;

    private int curPage = 1;

    private int totalPage = 0;

    private volatile boolean isLoading = false;

    private long lastPullTimeStamp = 0;

    public BaseListFragment() {
        super();
        objectList = new ArrayList<>();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_base_list,container,false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        findViews(view);
        initViews();
        initLogic();
        refreshData();
    }

    private void findViews(View parentView) {
        waitingProgressBar = (ProgressBar) parentView.findViewById(R.id.refresh_progress);
        swipeRefreshLayout = (SwipeRefreshLayout) parentView.findViewById(R.id.swipeRefreshLayout);
        contentRecyclerView = (RecyclerView) parentView.findViewById(R.id.recyclerview_content);
        statusMsgTv = (TextView) parentView.findViewById(R.id.tv_status_msg);
        statusMsgPanel = (RelativeLayout) parentView.findViewById(R.id.panel_fragment_status);
    }

    private void initViews() {
        layoutManager = new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false);
        contentRecyclerView.setLayoutManager(layoutManager);
        adapter = setupAdapter(objectList);
        contentRecyclerView.setAdapter(adapter);

        //实现下拉刷新
        swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,
                android.R.color.holo_orange_light, android.R.color.holo_green_light);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshData();
            }
        });

        //实现加载更多
        contentRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView,
                                             int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                lastVisibleItem = layoutManager.findLastVisibleItemPosition();
                if (newState == RecyclerView.SCROLL_STATE_IDLE
                        && lastVisibleItem + 1 == adapter.getItemCount()) {
                    if ((System.currentTimeMillis() - lastPullTimeStamp < 300)) {
                        if (curPage < totalPage && !isLoading) {
                            waitingProgressBar.setVisibility(View.VISIBLE);
                            isLoading = true;
                            curPage++;
                            new GetDataTask().execute();
                        }
                    }
                    lastPullTimeStamp = System.currentTimeMillis();
                }
            }

        });

        //点击错误页面重新加载
        statusMsgPanel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                refreshData();
            }
        });
    }

    private void  initLogic() {
        DATA_REQUEST_URL = setupDataRequestUrl();
    }

    private void refreshData() {
        curPage = 1;
        totalPage = 0;
        objectList.clear();
        isLoading = true;
        swipeRefreshLayout.setRefreshing(true);
        waitingProgressBar.setVisibility(View.VISIBLE);
        new GetDataTask().execute();
    }

    private class GetDataTask extends AsyncTask<String,Void,String> {

        @Override
        protected String doInBackground(String... params) {
            Map<String,String> urlParams = setupUrlParams();
            try {
                return HttpHelper.INSTANCE.post(DATA_REQUEST_URL,urlParams);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);
            isLoading = false;
            waitingProgressBar.setVisibility(View.INVISIBLE);
            swipeRefreshLayout.setRefreshing(false);
            if (StringUtils.INSTANCE.isEmpty(response)) {
                changeFragmentStatus(FragmentStatus.NETWORK_ERROR);
                return;
            }

            List<T> dataTemp = parseJson(response);
            objectList.addAll(dataTemp);
            adapter.notifyDataSetChanged();
            refreshStatus();
        }
    }

    //todo Replace With Status Pattern
    public void changeFragmentStatus(FragmentStatus status) {
        switch (status) {
            case NORMAL:
                if (contentRecyclerView.getVisibility() != View.VISIBLE) {
                    contentRecyclerView.setVisibility(View.VISIBLE);
                    statusMsgTv.setText(R.string.status_normal);
                    statusMsgPanel.setVisibility(View.INVISIBLE);
                }
                break;
            case NO_DATA:
                contentRecyclerView.setVisibility(View.INVISIBLE);
                statusMsgPanel.setVisibility(View.VISIBLE);
                statusMsgTv.setText(R.string.status_no_data);
                break;
            case NETWORK_ERROR:
            case REQUEST_ERROR:
                contentRecyclerView.setVisibility(View.INVISIBLE);
                statusMsgPanel.setVisibility(View.VISIBLE);
                statusMsgTv.setText(R.string.status_network_error);
                break;
        }
    }

    private void refreshStatus() {
        if (objectList.size() < 1) {
            changeFragmentStatus(FragmentStatus.NO_DATA);
        } else {
            changeFragmentStatus(FragmentStatus.NORMAL);
        }
    }

    public int getCurPage() {
        return curPage;
    }

    public RecyclerView getContentRecyclerView() {
        return contentRecyclerView;
    }

    public void updatePageNum(int curPage,int totalPage) {
        this.curPage = curPage;
        this.totalPage = totalPage;
    }

    protected abstract RecyclerView.Adapter setupAdapter(List<T> dataObjects);

    protected abstract String setupDataRequestUrl();

    protected abstract List<T> parseJson(String jsonStr);

    protected abstract Map<String,String> setupUrlParams();

}
